function echo<T>(arg: T): T {
  return arg;
}

const result = echo<number>(123);

function swap<T, U>(tuple: [T, U]): [T, U] {
  return [tuple[0], tuple[1]];
}

function echo1<T>(arg: T[]): T[] {
  console.log(arg.length);
  return arg;
}
const arr1 = echo1([1, 2, 3]);

interface IWithLength {
  length: number;
}
function echo2<T extends IWithLength>(arg: T): T {
  console.log(arg.length);
  return arg;
}

class Queue<T> {
  private data: T[] = [];
  push(item: T) {
    return this.data.push(item);
  }
  pop(): T {
    return this.data.shift();
  }
}

const queue = new Queue<number>();
queue.push(1);
const poped = queue.pop();
if (poped) {
  console.log(poped.toFixed());
}

interface KeyPair<T, U> {
  key: T;
  value: U;
}
let kp1: KeyPair<number, string> = { key: 1, value: "string" };
let kp2: KeyPair<string, number> = { key: "string", value: 1 };

let arr2: Array<number> = [1, 2, 3];
